<!DOCTYPE html>
<html>
<head>
<title>Thermodynamic Diagram</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
  }
  canvas {
    background-color: white;
    border: 1px solid #ccc;
  }
</style>
</head>
<body>
<canvas id="thermoDiagram" width="450" height="450"></canvas>
<script>
    const canvas = document.getElementById('thermoDiagram');
    const ctx = canvas.getContext('2d');

    // Helper function to draw a filled arrowhead at a point (x,y) pointing in a given direction (angle)
    function drawArrowhead(ctx, x, y, angle, size) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, -size / 2.5);
        ctx.lineTo(-size, size / 2.5);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }
    
    // --- General Styles ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.lineCap = 'round';

    // --- Draw Axes ---
    const originX = 70;
    const originY = 400;
    const axisEndX = 430;
    const axisEndY = 50;
    
    // V-axis (horizontal axis representing Volume)
    ctx.beginPath();
    ctx.moveTo(originX, originY);
    ctx.lineTo(axisEndX, originY);
    ctx.stroke();
    drawArrowhead(ctx, axisEndX, originY, 0, 12);

    // p-axis (vertical axis representing Pressure)
    ctx.beginPath();
    ctx.moveTo(originX, originY);
    ctx.lineTo(originX, axisEndY);
    ctx.stroke();
    drawArrowhead(ctx, originX, axisEndY, -Math.PI / 2, 12);

    // --- Draw Labels ---
    ctx.font = 'italic 24px Times New Roman';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 'p' label for the pressure axis
    ctx.fillText('p', originX, axisEndY - 20);
    
    // 'V' label for the volume axis
    ctx.fillText('V', axisEndX + 15, originY);
    
    // 'O' label for the origin
    ctx.font = '24px Times New Roman';
    ctx.fillText('O', originX - 20, originY + 20);
    
    // --- Draw the Thermodynamic Cycle Loop ---
    const centerX = 250;
    const centerY = 225;
    const radiusX = 110;
    const radiusY = 85;
    const rotation = -Math.PI / 10; // Approximately -18 degrees

    ctx.beginPath();
    ctx.ellipse(centerX, centerY, radiusX, radiusY, rotation, 0, 2 * Math.PI);
    ctx.stroke();

    // --- Draw Arrows on the Loop ---
    // The arrows indicate a counter-clockwise thermodynamic cycle.
    
    // Top arrow: on the upper branch, the path moves left (decreasing volume)
    // The tangent points generally up and to the left.
    const topArrowX = 165;
    const topArrowY = 165;
    const topArrowAngle = 0.85 * Math.PI; // Angle for "up and left" direction
    drawArrowhead(ctx, topArrowX, topArrowY, topArrowAngle, 12); 

    // Bottom arrow: on the lower branch, the path moves right (increasing volume)
    // The tangent points generally down and to the right.
    const bottomArrowX = 335;
    const bottomArrowY = 285;
    const bottomArrowAngle = -0.15 * Math.PI; // Angle for "down and right" direction
    drawArrowhead(ctx, bottomArrowX, bottomArrowY, bottomArrowAngle, 12);

    // --- Draw Caption ---
    ctx.font = '24px "KaiTi", "SimSun"'; // Standard Chinese fonts
    ctx.textAlign = 'center';
    ctx.fillText('热图 2.1.1', canvas.width / 2, 435);

</script>
</body>
</html>